using System;
using Buildin.Components;
using Buildin.Containers;
using Buildin.Systems;
using Core;
using Cysharp.Threading.Tasks;
using Ecs.Component;
using Ecs.System;
using Managers;
using Registry;
using ShawnFramework;
using Unity.Mathematics;
using UnityEngine;
using Random = UnityEngine.Random;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    // 地图有效尺寸
    public Rect bgRect;
    // Ecs世界
    private EcsWorld _world;
    public EcsWorld World => _world;
    // 地图划分网格
    private SpatialGrid _grid;
    public SpatialGrid Grid => _grid;
    // 系统驱动器
    private SystemRunner _runner;
    
    // 兵种召唤管理器
    public CallManager CallMgr = new();

    private void Awake()
    {
        Instance = this;
        InitEcsWorld();
        InitGrid();
        InitSystems();
    }

    private void OnDestroy()
    {
        _runner.Dispose();
        _grid.Dispose();
        _world.UnInit();
    }

    private void Update()
    {
        _runner.TickSystems(Time.deltaTime);
    }

    private void InitEcsWorld()
    {
        // 初始化Ecs世界
        _world = new EcsWorld();
        _world.Init();
        
        // 注册 所需原型
        _world.NewArchetype(
            EArchetypeRegistryID.Ball
            , typeof(Area2DComponent)
            , typeof(TransformComponent)
            , typeof(VelocityComponent)
            , typeof(AnimationComponent));

        _world.NewArchetype(
            EArchetypeRegistryID.Pet
            , typeof(Area2DComponent)
            , typeof(TransformComponent)
            , typeof(AnimationComponent));
    }

    private void InitGrid()
    {
        _grid = new SpatialGrid(new float2(400, 400), bgRect.size);
    }

    private void InitSystems()
    {
        _runner = new SystemRunner();
        _runner.RegisterSystem(new GridSystem(_world, _grid, EArchetypeRegistryID.Ball));
        _runner.RegisterSystem(new RollSystem(_world, EArchetypeRegistryID.Ball));
        // _runner.RegisterSystem(new RenderSystem(_world, EArchetypeRegistryID.Ball));
    }
    
    # region Test

    public int TotalBallCount = 0;
    // 异步任务管理器
    private readonly AsyncTaskAttacher _attacher = new();
    private async void OnGUI()
    {
        GUIStyle style = new GUIStyle
        {
            fontSize = 40,
            alignment = TextAnchor.MiddleCenter,
            normal =
            {
                textColor = Color.white
            }
        };

        GUILayoutOption[] options = new GUILayoutOption[]
        {
            GUILayout.Height(60),
            GUILayout.Width(200),
        };
        
        if (GUILayout.Button("生成1个", style, options))
        {
            TestNewOneEntity();
        }
        
        if (GUILayout.Button("生成100个", style, options))
        {
            _attacher.RunAnoymousTask(async (cancellationToken) =>
            {
                for (int i = 0; i < 100; ++i)
                {
                    await UniTask.DelayFrame(1, PlayerLoopTiming.Update, this.GetCancellationTokenOnDestroy());
                    TestNewOneEntity();
                }
            }).Forget();
        }

        if (GUILayout.Button("生成1000个", style, options))
        {
            _attacher.RunAnoymousTask(async (cancellationToken) =>
            {
                for (int i = 0; i < 1000;)
                {
                    await UniTask.DelayFrame(1, PlayerLoopTiming.Update, this.GetCancellationTokenOnDestroy());
                    for (int j = 0; j < 5; ++j)
                    {
                        TestNewOneEntity();
                        ++i;
                    }
                }
            }).Forget();
        }
    }

    private void TestNewOneEntity()
    {
        var areaComp = new Area2DComponent()
        {
            Center = new float2
            {
                x = Random.Range(bgRect.x, bgRect.x + bgRect.width),
                y = Random.Range(bgRect.y, bgRect.y + bgRect.height),
            },
            Radius = 100,
        };
        var transformComp = new TransformComponent()
        {
            Position = new float3(areaComp.Center.x, 0, areaComp.Center.y),
            Rotation = float3.zero,
            Scale = new float3(200, 200, 200),
        };
        var velocityComp = new VelocityComponent()
        {
            Velocity = new float2(Random.Range(-500, 500), Random.Range(-500, 500)),
        };
        var animComp = new AnimationComponent()
        {
            AnimId = 111,
            DefaultState = 0,
            State = 0,
            FrameIndex = 0,
            Timer = 0f,
            IsFirstFrameCurState = true,
        };
        _world.NewEntity(EArchetypeRegistryID.Ball, areaComp, transformComp, velocityComp, animComp);
        TotalBallCount++;
    }
    
    private void OnDrawGizmos()
    {
        if (!Application.isPlaying)
            return;
        // 绘制地图边界
        // Gizmos.color = Color.red;
        // Gizmos.DrawWireCube(new Vector2(bgRect.center.x, bgRect.center.y), new Vector2(bgRect.width, bgRect.height));
        // 绘制网格
        Gizmos.color = Color.cyan;
        _grid.OnDraw();
        // 绘制小球轮廓
        Gizmos.color = Color.green;
        using var areaCompsSlice = _world.GetEntityComponentDataMemorySlice<Area2DComponent>(EArchetypeRegistryID.Ball);
        foreach (var areaComp in areaCompsSlice)
        {
            Gizmos.DrawWireSphere(new (areaComp.Center.x, 0, areaComp.Center.y), areaComp.Radius);   
        }
    }
    
    # endregion
}
